﻿//each by:john
function each(object, callback, args)
{

    var name, i = 0, length = object.length;

    if (args)
    {

        if (length == undefined)
        {

            for (name in object)
                if (callback.apply(object[name], args) === false) break;
        } else

            for (; i < length; )
            if (callback.apply(object[i++], args) === false) break;


    } else
    {

        if (length == undefined)
        {

            for (name in object)
                if (callback.call(object[name], name, object[name]) === false) break;

        } else

            for (var value = object[0]; i < length && callback.call(value, i, value) !== false; value = object[++i]) { }

    }

    return object;
}

Array.prototype.inArray = function(value)
{
    var i;
    for (i = 0; i < this.length; i++)
    {
        if (this[i] === value)
        {
            return true;
        }
    }
    return false;
};

//trim
String.prototype.trim = function() {
    return this.replace(/(^\s*)|(\s*$)/g, '');
};

Object.extend = function(destination, source) {
    for (var property in source) {
        destination[property] = source[property];
    }
    return destination;
};

/*
dom相关方法
*/

//上一个子节点
function prev(elem)
{
    do
    {

        elem = elem.previousSibling;

    } while (elem && elem.nodeType != 1);

    return elem;
}

//最后一个子元素
function last(elem)
{

    elem = elem.lastChild;

    return elem && elem.nodeType != 1 ? prev(elem) : elem;
}

//根据标记获取元素
function tag(name, elem)
{
    return (elem || document).getElementsByTagName(name);
}

function id(name)
{
    return typeof name == "string" ? document.getElementById(name) : name;
}

//将文本转换为节点
function checkElem(elem)
{
    return elem && elem.constructor == String ? document.createTextNode(elem) : elem;
}

//在节点前插入新节点
function before(parent, before, elem)
{
    if (elem == null)
    {
        elem = before;
        before = parent;
        parent = before.parentNode;
    }
    parent.insertBefore(checkElem(elem), before);
}

//附加节点
function after(n, r)
{
    if (r.nextSibling)
        r.parentNode.insertBefore(n, r.nextSibling);
    else
        r.parentNode.appendChild(n);
}

function next(elem)
{
    do
    {
        elem = elem.nextSibling;
    } while (elem && elem.nodeType != 1);
    return elem;
}

// Remove a single Node from the DOM
function remove(elem)
{
    if (elem) elem.parentNode.removeChild(elem);
}


function parent(elem, num)
{
    num = num || 1;
    for (var i = 0; i < num; i++)
        if (elem != null) elem = elem.parentNode;
    return elem;
}


/* grab Elements from the DOM by className */
function getElementsByClass(searchClass, node, tag)
{
    var classElements = new Array();
    if (node == null)
        node = document;
    if (tag == null)
        tag = '*';
    var els = node.getElementsByTagName(tag);
    var elsLen = els.length;
    var pattern = new RegExp("(^|\\s)" + searchClass + "(\\s|$)");
    for (i = 0, j = 0; i < elsLen; i++)
    {
        if (pattern.test(els[i].className))
        {
            classElements[j] = els[i];
            j++;
        }
    }
    return classElements;
}

function create(elem)
{
    return document.createElementNS ?
        document.createElementNS('http://www.w3.org/1999/xhtml', elem) :
        document.createElement(elem);
}

function append(parent, elem)
{
    parent.appendChild(checkElem(elem));
}

function attr(elem, name, value)
{
    // Make sure that a valid name was provided
    if (!name || name.constructor != String) return "";
    // Figure out if the name is one of the weird naming cases
    name = { "for": "htmlFor", "class": "className"}[name] || name;
    // If the user is setting a value, also
    if (value != null)
    {
        // Set the quick way first
        elem[name] = value;
        // If we can, use setAttribute
        if (elem.setAttribute)
            elem.setAttribute(name, value);
    }
    // Return the value of the attribute
    return elem[name] || elem.getAttribute(name) || "";
}

/*
css相关的方法
*/

// Get a style property (name) of a specific element (elem)
function getStyle(elem, name)
{

    if (elem.style[name])
        return elem.style[name];
    // Otherwise, try to use IE’s method
    else if (elem.currentStyle)
        return elem.currentStyle[name];
    // Or the W3C’s method, if it exists
    else if (document.defaultView && document.defaultView.getComputedStyle)
    {
        // It uses the traditional ‘text-align’ style of rule writing, instead of textAlign
        name = name.replace(/([A-Z])/g, "-$1");
        name = name.toLowerCase();
        // Get the style object and get the value of the property (if it exists)
        var s = document.defaultView.getComputedStyle(elem, "");
        return s && s.getPropertyValue(name);
        // Otherwise, we’re using some other browser
    } else
        return null;
}

function hide(elem)
{

    var curDisplay = getStyle(elem, 'display');

    if (curDisplay != 'none')
        elem.$oldDisplay = curDisplay;

    elem.style.display = 'none';
}


function show(elem)
{

    elem.style.display = elem.$oldDisplay || 'block';
}

function addClass(elem, classname)
{
    elem.className += " " + classname;
}

function removeClass(elem, classname)
{
    elem.className = elem.className.replace(classname, " ");
}

/*
位置尺寸相关
*/

function pageX(elem)
{
    var p = 0;
    while (elem.offsetParent)
    {
        p += elem.offsetLeft;

        elem = elem.offsetParent;
    }
    return p;
}


function pageY(elem)
{
    var p = 0;

    while (elem.offsetParent)
    {

        p += elem.offsetTop;

        elem = elem.offsetParent;

    }
    return p;
}

function setX(elem, pos)
{

    elem.style.left = pos + "px";

}

function setY(elem, pos)
{

    elem.style.top = pos + "px";

}

// Find the full, possible, height of an element (not the actual,
// current, height)
function fullHeight(elem)
{
    // If the element is being displayed, then offsetHeight
    // should do the trick, barring that, getHeight() will work
    if (getStyle(elem, 'display') != 'none')
        return elem.offsetHeight || getHeight(elem);
    // Otherwise, we have to deal with an element with a display
    // of none, so we need to reset its CSS properties to get a more
    // accurate reading
    var old = resetCSS(elem, {
        display: '',
        visibility: 'hidden',
        position: 'absolute'
    });
    // Figure out what the full height of the element is, using clientHeight
    // and if that doesn't work, use getHeight
    var h = elem.clientHeight || getHeight(elem);
    // Finally, restore the CSS properties back to what they were        restoreCSS( elem, old );
    // and return the full height of the element
    return h;
}

// Find the full, possible, width of an element (not the actual,
// current, width)
function fullWidth(elem)
{
    // If the element is being displayed, then offsetWidth
    // should do the trick, barring that, getWidth() will work
    if (getStyle(elem, 'display') != 'none')
        return elem.offsetWidth || getWidth(elem);
    // Otherwise, we have to deal with an element with a display
    // of none, so we need to reset its CSS properties to get a more
    // accurate reading
    var old = resetCSS(elem, { display: '', visibility: 'hidden',
        position: 'absolute'
    });
    // Figure out what the full width of the element is, using clientWidth
    // and if that doesn't work, use getWidth
    var w = elem.clientWidth || getWidth(elem);
    // Finally, restore the CSS properties back to what they were
    restoreCSS(elem, old);
    // and return the full width of the element
    return w;

}


// A function used for setting a set of CSS properties, which
// can then be restored back again later
function resetCSS(elem, prop)
{
    var old = {};
    // Go through each of the properties
    for (var i in prop)
    {
        // Remember the old property value
        old[i] = elem.style[i];
        // And set the new value
        elem.style[i] = prop[i];
    }
    // Retun the set of changed values, to be used by restoreCSS
    return old;
}

// A function for restoring the side effects of the resetCSS function
function restoreCSS(elem, prop)
{
    // Reset all the properties back to their original values
    for (var i in prop)
        elem.style[i] = prop[i];
}

function nameSpace(a, b)
{
    var c = a.split(/\./);
    var d = window;
    for (var e = 0; e < c.length - 1; e++)
    {


        if (!d[c[e]])
        {

            d[c[e]] = {};
        }

        d = d[c[e]];
    }

    d[c[c.length - 1]] = b;
}